package com.akk.business;

import com.akk.PayConstants;
import com.akk.common.enums.Enums;
import com.akk.module.access.entity.AccessBind;
import com.akk.module.access.service.AccessService;
import com.akk.module.avs.entity.AvsCustomer;
import com.akk.module.avs.entity.AvsPayCashBind;
import com.akk.module.avs.entity.AvsPayOrder;
import com.akk.module.avs.enums.AvsTransferStatus;
import com.akk.module.avs.enums.HxtEnums;
import com.akk.module.avs.model.request.*;
import com.akk.module.avs.service.AvsCustomerService;
import com.akk.module.avs.service.AvsPayCashBindService;
import com.akk.module.avs.service.AvsPayOrderService;
import com.akk.module.hlbpay.model.HlbTransferQueryResponse;
import com.akk.module.hxt.model.*;
import com.akk.module.hxt.service.HxtService;
import com.akk.module.hxt.utils.HxtUtils;
import com.akk.utils.RestResponse;
import com.google.gson.Gson;
import org.apache.commons.httpclient.HttpStatus;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class AvsHxtPayBusiness {

    @Autowired
    private HxtService hxtService;

    @Autowired
    private AvsPayCashBindService cashBindService;

    @Autowired
    private AvsPayOrderService orderService;

    @Autowired
    private AvsCustomerService customerService;

    @Autowired
    private AccessService accessService;

    @Value("${server.url}")
    private String serverUrl;

    // 查询开卡
    public RestResponse openCardQuery(String cashBindId, String orderNum, String payerId) {
        List<AvsPayOrder> orders = orderService.findByOrderNum(orderNum);
        if (orders.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单信息不存在");
        AvsPayOrder order = orders.get(0);
        if (!order.getPayerId().equals(payerId.trim()))
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "非法请求");
        List<AvsPayCashBind> cashBinds = cashBindService.findByCashBinIdAndIsDeposit(payerId, 1);
        if (cashBinds.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "没有绑定结算卡");
        AvsPayCashBind cashBind = cashBinds.get(0);
        OpenCardQueryRequest request = new OpenCardQueryRequest();
        request.setOrderId(cashBindId);
        request.setMerId(payerId);
        request.setTxnTime(new SimpleDateFormat("yyyyMMddHHmmss").format(order.getCreateDate()));
        RestResponse restResponse = hxtService.openCardQuery(request);
        if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            OpenCardQueryResponse response = (OpenCardQueryResponse) restResponse.getResult();
            if (response.getActivateStatus().equals("1")) {
                if (response.getAccNo().equals(cashBind.getLastFourNum()))
                    return RestResponse.build(response.getTokenPayData());
            }
            return RestResponse.build("20017", "未开卡");
        }
        return restResponse;
    }

    // 开卡
    public RestResponse openCard(String payerId, String cashBindId, String orderNum) {
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>开卡");
        System.out.println(payerId + "-" + cashBindId + "-" + orderNum);
        AvsCustomer customer = customerService.findByCustomerId(payerId);
        if (customer == null)
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "用户信息不存在");
        AccessBind accessBind = accessService.findAccessBindById(cashBindId);
        if (accessBind == null)
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "银行卡信息不存在");
        HxtOpenCardRequest request = new HxtOpenCardRequest();
        request.setCardNo(accessBind.getCardNum());
        request.setOrderId(cashBindId);
        request.setFrontUrl(serverUrl + "/thmlfApi/avs/hxtpay/quickpaycallback?payerId=" + payerId + "&orderNum=" + orderNum);
        request.setBackUrl(serverUrl + "/thmlfApi/avs/hxtpay/opencardnotify");
        System.out.println("back:" + request.getBackUrl());
        request.setMerId(payerId);
        request.setTxnTime(HxtUtils.getTime());
        RestResponse restResponse = hxtService.openCardAPI(request);
        if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            HxtOpenCardResponse response = (HxtOpenCardResponse) restResponse.getResult();
            return RestResponse.build(response.getHtml());
        }
        return restResponse;
    }

    // 开卡异步通知
    public void openCardNotify(HttpServletRequest servletRequest) {
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>开卡通知");
        HxtOpenCardNotifyRequest request = new Gson().fromJson(HxtUtils.readContent(servletRequest), HxtOpenCardNotifyRequest.class);
        System.out.println(new Gson().toJson(request));
        if (request.getRespCode().equals("00") && request.getActivateStatus().equals("1")) {
            AccessBind accessBind = accessService.findAccessBindById(request.getOrderId());
            accessBind.setToken(request.getTokenPayData().substring(request.getTokenPayData().indexOf("token=") + 6, request.getTokenPayData().indexOf("&trId=")));
            accessService.updateBind(accessBind);
        }
    }

    // 回调
    public String quickPayCallBack(String payerId, String orderNum, HttpServletRequest request, HttpServletResponse response) {
        try {
            response.sendRedirect(serverUrl + "/pay/hxtpay.html?payerId=" + payerId + "&orderNum=" + orderNum + "&gateway=hxtpay");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    // 发送交易短信
    public RestResponse sendSMS(HxtSendSMSRequest request, BindingResult result) {
        if (result.hasErrors())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, result.getFieldError().getDefaultMessage());
        AvsCustomer customer = customerService.findByCustomerId(request.getPayerId());
        if (customer == null)
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "用户信息不存在");
        List<AvsPayOrder> orders = orderService.findByOrderNum(request.getOrderNum());
        if (orders.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单信息不存在");
        AvsPayOrder order = orders.get(0);
        if (!order.getPayerId().equals(request.getPayerId()))
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单信息错误");
        List<AvsPayCashBind> cashBinds = cashBindService.findByCashBinIdAndIsDeposit(request.getPayerId(), 1);
        if (cashBinds.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "没有绑定结算卡");
        List<AccessBind> accessBinds = accessService.findByPayerIdAndToken(request.getPayerId(), request.getToken());
        if (accessBinds.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "银行卡信息有误，或绑定通道失效");
        SendSMSRequest smsRequest = new SendSMSRequest();
        smsRequest.setMerId(request.getPayerId());
        smsRequest.setOrderId(request.getOrderNum());
        smsRequest.setTxnTime(new SimpleDateFormat("yyyyMMddHHmmss").format(order.getCreateDate()));
        smsRequest.setTxnAmt((int) (order.getAmountTotal() * 100) + "");
        smsRequest.setRealName(cashBinds.get(0).getHoldName());
        smsRequest.setIdentityCard(cashBinds.get(0).getIdCard());
        smsRequest.setCardNo(cashBinds.get(0).getCardNum());
        smsRequest.setPhoneNo(accessBinds.get(0).getPhone());
        System.out.println(order.getCreateDate().getTime());
        smsRequest.setToken(request.getToken());
        order.setPayBank(cashBinds.get(0).getBankName());
        order.setPayCardNo(accessBinds.get(0).getCardNum());
        orderService.update(order);
        RestResponse restResponse = hxtService.sendSMS(smsRequest);
        if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            SendSMSResponse response = (SendSMSResponse) restResponse.getResult();
            return RestResponse.build("success");
        }
        return restResponse;
    }

    // 交易消费
    public RestResponse payment(HxtPaymentRequest request, BindingResult result) {
        if (result.hasErrors())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, result.getFieldError().getDefaultMessage());
        AvsCustomer customer = customerService.findByCustomerId(request.getPayerId());
        if (customer == null)
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "用户信息不存在");
        List<AvsPayOrder> orders = orderService.findByOrderNum(request.getOrderNum());
        if (orders.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单信息不存在");
        AvsPayOrder order = orders.get(0);
        if (!order.getPayerId().equals(request.getPayerId()))
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单信息错误");
        List<AvsPayCashBind> cashBinds = cashBindService.findByCashBinIdAndIsDeposit(request.getPayerId(), 1);
        if (cashBinds.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "没有绑定结算卡");

        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setMerId(request.getPayerId());
        paymentRequest.setBackUrl(serverUrl + "/thmlfApi/avs/hxtpay/paymentback"); // 交易通知
        paymentRequest.setWithdrawUrl(serverUrl + "/thmlfApi/avs/hxtpay/paymentnotify");// 代付通知
        paymentRequest.setOrderId(order.getOrderNum());
        paymentRequest.setTxnTime(new SimpleDateFormat("yyyyMMddHHmmss").format(order.getCreateDate()));
        paymentRequest.setTxnAmt((int) (order.getAmountTotal() * 100) + "");
        paymentRequest.setToken(request.getToken());
        paymentRequest.setSettleCycle(HxtEnums.SettleCycle.D0.getValue());
        paymentRequest.setSmsCode(request.getSmsCode());
        paymentRequest.setSettleAmt((int) (order.getRealAmount() * 100) + "");
        order.setCashCardNo(cashBinds.get(0).getCardNum());
        order.setCollecBank(cashBinds.get(0).getBankName());
        RestResponse restResponse = hxtService.payment(paymentRequest);
        if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            PaymentResponse response = (PaymentResponse) restResponse.getResult();
            order.setOutTradeNum(response.getQueryId());
            order.setTransDate(new Date());
            restResponse = RestResponse.build("success");
        }
        orderService.update(order);
        return restResponse;
    }

    // 代付通知
    public void paymentNotify(HttpServletRequest servletRequest) {
        System.out.println("代付通知》》》》》》》》》》》》》》》》》》》》》》》》》");
        HxtPayDepositNotifyRequest request = new Gson().fromJson(HxtUtils.readContent(servletRequest), HxtPayDepositNotifyRequest.class);
        List<AvsPayOrder> orders = orderService.findByOrderNum(request.getOrderId());
        if (orders.isEmpty())
            return;
        AvsPayOrder order = orders.get(0);
        if (request.getRespCode().equals("00")) {
            order.setStatus(Enums.OrderStatusEnum.SUCCESS_DEPOSIT.getValue());
            order.setFinishDate(new Date());
        } else {
            order.setStatus(Enums.OrderStatusEnum.SUCCESS_PAYED.getValue());
        }
        orderService.update(order);
    }

    // 交易通知
    public String paymentBack(HttpServletRequest servletRequest) {
        System.out.println("消费通知》》》》》》》》》》》》》》》》》》》》》》》》》");
        HxtPaymentNotifyRequest request = new Gson().fromJson(HxtUtils.readContent(servletRequest), HxtPaymentNotifyRequest.class);
        List<AvsPayOrder> orders = orderService.findByOrderNum(request.getOrderId());
        if (orders.isEmpty())
            return "error";
        AvsPayOrder order = orders.get(0);
        if (request.getRespCode().equals("00") && order.getStatus().equals(Enums.OrderStatusEnum.NO_PAYED.getValue())) {
            order.setTransDate(new Date());
            order.setStatus(Enums.OrderStatusEnum.DOING.getValue());
            orderService.update(order);
        }
        return "success";
    }


    // 订单信息
    public RestResponse orderInfo(String payerId, String orderNum, String card) {
        AccessBind accessBind = accessService.findAccessBindById(card);
        if (accessBind == null)
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "银行卡信息不存在");
        List<AvsPayOrder> orders = orderService.findByOrderNum(orderNum);
        if (orders.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单不存在");
        AvsPayOrder order = orders.get(0);
        if (!order.getPayerId().equals(payerId))
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "非法请求");
        order.setCashCardNo(accessBind.getCardNum());
        order.setPayBank(accessBind.getCardName());
        orderService.update(order);
        Map result = new HashMap();
        result.put("amount", order.getAmountTotal());
        result.put("orderNum", order.getOrderNum());
        result.put("cardNum", order.getCashCardNo());
        return RestResponse.build(result);
    }

    // 支付查询
    public RestResponse payProgressQuery(String orderNum) {
        List<AvsPayOrder> orders = orderService.findByOrderNum(orderNum);
        if (orders.isEmpty())
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单不存在");
        AvsPayOrder order = orders.get(0);
        WithdrawQueryRequest withdrawQueryRequest = new WithdrawQueryRequest();
        withdrawQueryRequest.setMerId(PayConstants.HXT_MER_ID);
        withdrawQueryRequest.setOrderId(orderNum);
        withdrawQueryRequest.setTxnTime(new SimpleDateFormat("yyyyMMddHHmmss").format(order.getCreateDate()));
        RestResponse restResponse = hxtService.withdrawQuery(withdrawQueryRequest);
        if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            WithdrawQueryResponse response = (WithdrawQueryResponse) restResponse.getResult();
            return RestResponse.build(response);
        }
        return restResponse;
    }


    //
    public RestResponse transferQuery(AvsPayOrder order) {
        RestResponse restResponse = payProgressQuery(order.getOrderNum());
        if (order.getStatus() < Enums.OrderStatusEnum.SUCCESS_PAYED.getValue()) {
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "订单付款暂未成功");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(order.getTransDate());
        Calendar nowTime = Calendar.getInstance();
        nowTime.setTime(new Date());
        if (((calendar.get(Calendar.HOUR_OF_DAY) >= 17 && calendar.get(Calendar.MINUTE) >= 30)
                || (calendar.get(Calendar.HOUR_OF_DAY) <= 0 && calendar.get(Calendar.MINUTE) <= 10))
                && ((nowTime.get(Calendar.HOUR_OF_DAY) >= 17 && nowTime.get(Calendar.MINUTE) >= 30)
                || (nowTime.get(Calendar.HOUR_OF_DAY) <= 0 && nowTime.get(Calendar.MINUTE) <= 10))) {
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, "此通道结算时间 00:10 - 17：30 ，如刷卡成功未到账，请于次日00：10后查询");
        } else if (restResponse.getCode().equals(String.valueOf(HttpStatus.SC_OK))) {
            return RestResponse.build("1001", "此订单已经结算成功，如果长时间未到账，请联系客服处理。");
        } else {
            return RestResponse.build(RestResponse.AVS_ERROR_CODE, restResponse.getMessage());
        }
    }

    public RestResponse depositProgress(AvsPayOrder order) {
        RestResponse restResponse = transferQuery(order);
        int status = 0;
        if (Objects.equals(order.getStatus(), Enums.OrderStatusEnum.NO_PAYED.getValue())) {
            status = 0;
        } else if (restResponse.getCode().equals("20002")) {
            return restResponse;
        } else if (Objects.equals(order.getStatus(), Enums.OrderStatusEnum.SUCCESS_PAYED.getValue())) {
            status = 1;
        } else if (Objects.equals(order.getStatus(), Enums.OrderStatusEnum.SUCCESS_DEPOSIT.getValue())
                && restResponse.getCode().equals("1001")) {
            status = 4;
        }
        return RestResponse.build(status);
    }

    public void test() {
        RestResponse restResponse = payProgressQuery("LO12436368469107");
        return;
    }
}
